home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
332_01
/
jotto.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-23
|
14KB
|
673 lines
/*- -*- Fundamental -*-
*
* Facility: jotto(6)
*
* File: jotto.c
*
* Associated files: - [ none]
*
* Description: Plays the game of jotto
*
* Notes: No rules included.
*
* Portability: Edited to conform to X/Open Portability Guide,
* ed. 3, 1988
*
* Author: David M. Fogg
* 2632 N.E. Fremont
* Portland, OR 97212
*
* Editor: Anders Thulin
* Rydsvagen 288
* S-582 50 Linkoping
* SWEDEN
*
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Copyright (c) 1981 by David M. Fogg
*
* Permission is herewith granted for noncommercial distribution
* through the BDS User's Group; any and all forms of commercial
* redistribution are strenuously unwished-for.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
* Edit history :
*
* Vers Ed Date By Comments
* ---- --- ---------- ---------------- -------------------------------
* 1.0 0 1980-11-13 David M. Fogg Creation day
* 1 1980-11-18 David M. Fogg Creation ... finished
* 2 1980-11-10 David M. Fogg Bugwork
* 1.1 3 1988-10-25 Anders Thulin Many BDS-isms removed to make
* program K&R compatible. General
* cleanup for portability. Added
* some comments.
*
*/
/* - - Configuration options: - - - - - - - - - - - - - - - - - - - - - - - */
/*
*
* The following environments are supported:
*
* ANSI ANSI C
* BSD Berkeley UNIX
* SV2 AT&T UNIX System V.2
* XPG3 X/Open Portability Guide, ed. 3
* ZTC205 MS-DOS + Zortech C 2.05
*
* If you have an ANSI C conforming compiler, define ANSI. Otherwise,
* use the definition that best matches your environment.
*
*/
#define ANSI 0 /* 1 -> ANSI C, 0 -> K&R */
#define BSD 0
#define SV2 0
#define XPG2 0
#define ZTC205 1
#if ANSI
# include <ctype.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
#endif
#if BSD
# include <ctype.h>
# include <stdio.h>
# include <string.h>
typedef long time_t;
extern void exit();
extern int rand();
extern void srand();
extern time_t time();
#endif
#if SV2
# include <ctype.h>
# include <stdio.h>
# include <string.h>
typedef long time_t;
extern void exit();
extern int rand();
extern void srand();
extern time_t time();
#endif
#if XPG3
# include <ctype.h>
# include <stdio.h>
# include <string.h>
typedef long time_t; /*[???] or should it be time_t from <sys/types.h> ? */
extern void exit();
extern int rand();
extern void srand();
extern time_t time();
#endif
#if ZTC205
# include <ctype.h>
# include <stdio.h>
# include <string.h>
typedef long time_t;
extern void exit();
extern int rand();
extern void srand();
extern time_t time();
#endif
# include <curses.h>
/*
* Tweakables:
*
* The reason ALPHA_SIZE has been declared as a macro is that some
* compilers handle sizeof("<string>") as a synonym to sizeof(char *),
* which is wrong. ALPHA_SIZE should be defined to be the number
* of characters in the string ALPHABET.
*
*/
#define WORD_FILE "jotto.wds" /* default word file */
#define MAXWORDS 600 /* max nr of words in word file */
#define ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define ALPHA_SIZE 26
/* Code for RETURN/ENTER key -- some systems use \r, some \n */
#define RETURN '\n'
/*
* Non-tweakables:
*
*/
#ifndef TRUE
# define TRUE 1
# define FALSE 0
#endif
#define LETS 5 /* letters/word */
#define ISCORE 21 /* initial score */
/* screen layout parameters */
#define XTITLE 40 /* Title loc */
#define YTITLE 1
#define XPROMPT 33 /* prompt loc */
#define YPROMPT 4
#define XSCORE 3 /* score col */
#define XGUESS 10 /* guess col */
#define XMATCH 17 /* match col */
#define XSTATE 20 /* status col */
#define YHEAD 0 /* header row */
#define YFIRST 2 /* first guess row */
#define XLABELS 33 /* list labels col */
#define XLISTS 42 /* lists cols */
#define YYES 6 /* confirmed letters row */
#define YNO 8 /* eliminated letters row */
#define YPOSS 10 /* possible letters row */
#define XINST 30 /* instructions loc */
#define YINST 13
/*
* Global variables
*
*/
static int wordok, giveup;
static int score;
static char word[LETS+3];
static char guess[LETS+1], gots[LETS+1];
static int count;
static char guesslis[ISCORE+1][LETS+1];
static int changed;
static char nots[ALPHA_SIZE],
maybes[ALPHA_SIZE];
static char alphabet[] = ALPHABET;
/*
* Local functions:
*
*/
#ifdef __STDC__
static void dochange(void);
static void doguess(void);
static void doscreen(void);
static void dostate(int s);
static int getlet(void);
static void getword(char *wd);
static int inset(char *string, int ch);
static void inword(int x, int y, char *p, char *w);
static void modgot (int old, int new);
static int nomore(void);
static void printset(char *s);
static void xfer (int l, char *src, char *dest);
#else
static void dochange();
static void doguess();
static void doscreen();
static void dostate();
static int getlet();
static void getword();
static int inset();
static void inword();
static void modgot ();
static void printset();
static int nomore();
static void xfer ();
#endif
/*
* Routine: dochange
*
* Description: Read change commands from the terminal and
* perform the changes.
*
*/
static void dochange ()
{
int ch;
int sc;
char let;
static char legals[] = {'A', '+', '=', '_', 'N', '+', RETURN, '\0'};
changed = 0;
wordok = FALSE;
mvaddstr(YPROMPT, XPROMPT, "Change: "); refresh();
do {
if (islower(ch = getch())) {
ch = toupper(ch);
}
} while (inset(legals, ch) == 0);
refresh();
if (ch == 'A')
return;
else
wordok = TRUE;
while (ch != RETURN && changed < LETS) {
++changed;
switch (ch) {
case '=': ch = '+'; break;
case '_': ch = '-';
}
addch(ch);
let = getlet(); addch(' ');
switch (ch) {
case '+': modgot(' ', let); break;
case '-': modgot(let, ' '); break;
case 'N': xfer(let, maybes, nots); break;
case 'M': xfer(let, nots, maybes); break;
}
refresh();
do {
ch = toupper(getch());
} while (inset(legals, ch) == 0);
refresh();
}
if (changed > 0) {
move(YPROMPT, XPROMPT); clrtoeol();
move(YYES, XLISTS); addstr(gots);
move(YNO, XLISTS); printset(nots);
move(YPOSS, XLISTS); printset(maybes);
for (sc = ISCORE; sc >= score ; --sc) dostate(sc);
dochange();
}
}
/*
* Routine: doguess
*
* Description: Input guess from user and process it.
*
*/
static void doguess ()
{
int i, j, y;
char str[LETS+1];
/* 1. Get guess from user: */
y = YFIRST + ISCORE - score;
move(y, XSCORE); printw("%4d", score);
inword(XGUESS-1, y, " ", guess);
/* 2. Process guess: */
if (strcmp(guess, "?????") == 0) {
giveup = TRUE;
} else {
giveup = FALSE;
strcpy(str, word); count = 0;
for (i = 0; i < LETS; ++i) {
if ((j = inset(str, guess[i])) > 0) {
++count;
str[j-1] = tolower(str[j-1]);
}
}
printw("%3d", count);
strcpy(guesslis[score], guess);
dostate(score);
}
}
/*
* Routine: doscreen
*
* Description: Clears the screen. Prints guess columns, some
* help text and various other stuff.
*
*/
static void doscreen()
{
clear();
mvaddstr(YTITLE, XTITLE, "--> J O T T O <--");
mvaddstr(YHEAD, XSCORE, "Score Guess # STATE");
mvaddstr(YHEAD+1, XSCORE, "===== ===== = =====");
move(YYES, XLABELS+3); addstr("YES:");
move(YNO, XLABELS+4); addstr("NO:");
move(YPOSS, XLABELS+1); addstr("MAYBE:");
move(YPOSS, XLISTS); printset(maybes);